/*
 * PipedCommand.cc
 *
 *  Created on: Jul 10, 2012
 *      Author: victor
 */

#include "PipedCommand.h"

PipedCommand::PipedCommand(){
	hasComms = false;
	commands = new vector<Command*>();
}

PipedCommand::~PipedCommand(){
	//TODO: implement this
}

void PipedCommand::addCommand(Command * newCommand){
	hasComms = true;
	commands->push_back(newCommand);
}

bool PipedCommand::hasCommands(){
	return hasComms;
}

bool PipedCommand::executeCommands(bool execute){
	// http://stackoverflow.com/questions/5189475/passing-a-pipe-as-a-parameter-in-exec
	// http://stackoverflow.com/questions/1653340/exec-and-fork
	int pipes[commands->size()-1];
	int child_pid;

	if(pipe(pipes) < 0){ // create pipelines
		perror("pipe"); // something has gone wrong
		return false;
	}

	//TODO: atm double pipelines are being used,
	for(unsigned int i = 0; i < commands->size()-1; i++){
		switch(child_pid = fork()){
		case -1: // failed to create new process
			perror("fork");
			return false;
			break;

		case 0: // child process
			dup2(pipes[READ],STDIN_FILENO); // send to std input
			close(pipes[WRITE]); // close unused part of pipe
			commands->at(i+1)->execute();
			break;

		default: // parent process
			dup2(pipes[WRITE], STDOUT_FILENO);
			close(pipes[READ]); // close unused part of pipe
			commands->at(i)->execute();
			break;
		}
	}
	return true;

}
